home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’93
/
Wavy
/
Wavy.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-06-18
|
6KB
|
247 lines
/*
Wavy.c
Make everything nice and wavy.
Known bugs:
If you launch applications and they call InitCursor, the cursor will disappear.
What can we do to prevent this? Perhaps switch back to the on-screen base address
whenever the cursor calls are called (patch into the low-level cursor vectors).
Escape and Cancel do not work in the main dialog. We should really write a dialog
filter function that will make everything work.
*/
#include <QDOffscreen.h>
#include <Retrace.h>
#include "Wavy.h"
static GDHandle FindGoodScreen(void);
static Boolean IsGoodScreen(GDHandle);
static BitMap *CopyBitsParameter(PixMapHandle);
static pascal void ColumnTask(void);
typedef struct {
VBLTask task;
char *sourceBase;
char *destinationBase;
short columnNumber;
short frameNumber;
short totalColumns;
short totalFrames;
short width;
short height;
short rowBytes;
Rect screenRect;
short *frameCode[frameCount];
} HonkinVBLTask;
static GDHandle FindGoodScreen(void)
{
GDHandle device;
device = GetMainDevice();
if (IsGoodScreen(device))
return device;
for (device = GetDeviceList(); device != nil; device = GetNextDevice(device))
if (IsGoodScreen(device))
return device;
return nil;
}
static Boolean IsGoodScreen(GDHandle screen)
{
return (**(**screen).gdPMap).cmpSize == 8;
}
static BitMap *CopyBitsParameter(PixMapHandle pixmap)
{
return (BitMap *)pixmap;
}
static pascal void ColumnTask(void)
{
HonkinVBLTask *task;
Rect column;
short hOffset;
Point zeroOffset;
asm {
move.l a0,task
}
column = task->screenRect;
hOffset = task->columnNumber * columnSize;
column.left += hOffset;
column.right = column.left + columnSize;
zeroOffset.h = 0;
zeroOffset.v = 0;
ShieldCursor(&column, zeroOffset);
DrawColumn(task->sourceBase + hOffset, task->destinationBase + hOffset, task->frameNumber, task->frameCode);
ShowCursor();
if (++task->columnNumber >= task->totalColumns) {
task->columnNumber = 0;
if (++task->frameNumber >= task->totalFrames) {
task->frameNumber = 0;
}
}
task->task.vblCount = 1;
}
main()
{
Boolean newWaviness, enoughMemory;
GDHandle screen;
PixMapHandle screenPix;
short width, height, rowBytes;
long screenSize;
Ptr screenBase, offscreenBase;
HonkinVBLTask task;
EventRecord event;
long amplitude;
DialogPtr dialog;
short item;
Handle itemHandle;
Str255 string;
short frameNumber;
Rect itemBox;
InitGraf(&qd.thePort);
InitMenus();
InitWindows();
TEInit();
InitDialogs(nil);
SetMenuBar(GetNewMBar(128));
AddResMenu(GetMHandle(128), 'DRVR');
DrawMenuBar();
InitCursor();
screen = FindGoodScreen();
if (screen == nil) {
Alert(131, nil);
return;
}
screenPix = (**screen).gdPMap;
width = (**screenPix).bounds.right - (**screenPix).bounds.left;
height = (**screenPix).bounds.bottom - (**screenPix).bounds.top;
rowBytes = (**screenPix).rowBytes & 0x7FFF;
if (width % columnSize != 0) {
Alert(131, nil);
return;
}
screenSize = height * (long) rowBytes;
offscreenBase = NewPtr(screenSize);
if (offscreenBase == nil) {
Alert(130, nil);
return;
}
restart:
newWaviness = false;
dialog = GetNewDialog(129, nil, nil);
GetDItem(dialog, 1, nil, nil, &itemBox);
InsetRect(&itemBox, -4, -4);
SetPort(dialog);
PenSize(3, 3);
FrameRoundRect(&itemBox, 16, 16);
SelIText(dialog, 3, 0, 32767);
for (;;) {
ModalDialog(nil, &item);
if (item != ok) ExitToShell();
GetDItem(dialog, 3, nil, &itemHandle, nil);
GetIText(itemHandle, string);
StringToNum(string, &litude);
if ((short)amplitude >= 1) break;
}
DisposeDialog(dialog);
dialog = GetNewDialog(128, nil, nil);
GetDItem(dialog, 1, nil, &itemHandle, nil);
DrawDialog(dialog);
enoughMemory = InitColumns(amplitude, width, height, rowBytes, task.frameCode, itemHandle);
DisposeDialog(dialog);
if (!enoughMemory) {
Alert(130, nil);
return;
}
screenBase = (**screenPix).baseAddr;
HideCursor();
BlockMove(screenBase, offscreenBase, screenSize);
ShowCursor();
(**screenPix).baseAddr = offscreenBase;
task.task.qType = vType;
task.task.vblAddr = ColumnTask;
task.task.vblCount = 1;
task.task.vblPhase = 0;
task.sourceBase = offscreenBase;
task.destinationBase = screenBase;
task.columnNumber = 0;
task.frameNumber = 0;
task.totalColumns = width / columnSize;
task.totalFrames = frameCount;
task.width = width;
task.height = height;
task.rowBytes = rowBytes;
task.screenRect = (**screenPix).bounds;
if (SlotVInstall((QElemPtr)&task, 0) != noErr) {
goto done;
}
for (;;) {
long menuItem = 0;
GetNextEvent(everyEvent, &event);
if (event.what == keyDown)
menuItem = MenuKey(event.message & 0xFF);
else if (event.what == mouseDown) {
short which;
WindowPtr window;
which = FindWindow(event.where, &window);
if (which == inMenuBar)
menuItem = MenuSelect(event.where);
}
if (menuItem == ((128L<<16) | 1)) {
Alert(132, nil);
} else if (menuItem == ((129L<<16) | 1)) {
newWaviness = true;
break;
} else if (menuItem == ((129L<<16) | 3))
break;
else if ((menuItem>>16) == 128) {
Str255 name;
GetItem(GetMHandle(128), menuItem & 0xFFFF, name);
OpenDeskAcc(name);
}
HiliteMenu(0);
}
SlotVRemove((QElemPtr)&task, 0);
for (frameNumber = 0; frameNumber < frameCount; ++frameNumber)
DisposePtr((Ptr)task.frameCode[frameNumber]);
done:
(**screenPix).baseAddr = screenBase;
HideCursor();
BlockMove(offscreenBase, screenBase, screenSize);
InitCursor();
if (newWaviness)
goto restart;
}